package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// 初始化一个基础的上下文对象
	baseCtx := context.Background()

	// 在基础上下文上添加键值对"a":"b"，并将其传递给新创建的goroutine
	ctx := context.WithValue(baseCtx, "a", "b")
	go func(c context.Context) {
		// 新创建的goroutine从上下文中取出键"a"对应的值并打印
		fmt.Println(c.Value("a"))
	}(ctx)

	// 创建一个带有超时设置的上下文对象，超时时间为1秒
	timeoutCtx, cancel := context.WithTimeout(baseCtx, time.Second)
	// 当goroutine执行完毕后，取消创建的上下文对象以避免内存泄漏
	defer cancel()

	go func(ctx context.Context) {
		// 创建一个定时器，每秒触发一次
		ticker := time.NewTicker(1 * time.Second)
		// 使用select语句监听多个channel
		for _ = range ticker.C {
			select {
			case <-ctx.Done():
				// 当上下文对象被取消或超时时，打印信息并退出goroutine
				fmt.Println("child process interrupt……")
				return
			default:
				// 默认情况下执行的逻辑，这里只是简单地打印一条信息
				fmt.Println("enter default")
			}
		}
	}(timeoutCtx)

	// 主goroutine等待带有超时设置的上下文对象被取消
	select {
	case <-timeoutCtx.Done():
		// 超时后，暂停1秒，然后打印一条信息
		time.Sleep(1 * time.Second)
		fmt.Println("main process exit!")
	}
	// 下面的代码被注释掉了，如果需要，可以取消注释以观察不同的行为
	//time.Sleep(time.Seconcond * 5)
}
